package cz.possoft.serializable.clovece.game;

import java.util.Collection;
import java.util.HashSet;

import cz.possoft.generic.utils.GenericUtils;

/**
 * One field on the board.
 * 
 * @author <a href="mailto:mposolda@gmail.com">Marek Posolda</a>
 */
public class CloveceField
{
   // identificator of the field. Key points are:
   // 1) id of normal fields is 1-40
   // 2) id of fields of white player home are 101-104, id of fields of black player home are 201-204
   // 3) id of fields of white player start is 1001-1004, id of fields of black player start are 2001-2004 
   private final int id;
   
   // 0 if it not start field, GenericUtils.WHITE if it is start field of white player, GenericUtils.BLACK of start field of black player
   private final int startFieldOnBoard;
   
   // indicator if field is part of the home of some player
   private final boolean partOfHome;
   
   // indicator of color if field is home of some player 
   private final int colorIfPartOfHome;   
   
   // indicator if field is part of the start of some player
   private final boolean partOfStart;
   
   // indicator of color if field is start of some player 
   private final int colorIfPartOfStart;   
   
   // neighbors of this field where some figurka can play. note: it's not final but it's very close to final (can't be changed after initialize)
   private Collection<CloveceField> neighborsToDirection = new HashSet<CloveceField>();
   
   // neighbor of this field from where we can play to this field. note: it's not final but it's very close to final (can't be changed after initialize)
   private CloveceField neigborFromDirection;   
   
   // color of figurka on the field. (This is only field which is not final)
   private int color;      
   
   public CloveceField(int id)
   {
      this.id = id;
            
      if (id == ClovecePole.WHITE_PLAYER_START_FIELD_ON_BOARD)
      {
         startFieldOnBoard = GenericUtils.COLOR_WHITE; 
      }
      else if (id == ClovecePole.BLACK_PLAYER_START_FIELD_ON_BOARD)
      {
         startFieldOnBoard = GenericUtils.COLOR_BLACK; 
      }
      else
      {
         startFieldOnBoard = GenericUtils.COLOR_NEUTRAL;
      }
      
      if (id>=100 && id<199)
      {
         partOfHome = true;
         colorIfPartOfHome = GenericUtils.COLOR_WHITE;
      }
      else if (id>=200 && id<299)
      {
         partOfHome = true;
         colorIfPartOfHome = GenericUtils.COLOR_BLACK;         
      }
      else
      {
         partOfHome = false;
         colorIfPartOfHome = GenericUtils.COLOR_NEUTRAL;             
      }
      
      if (id>=1000 && id<1999)
      {
         partOfStart = true;
         colorIfPartOfStart = GenericUtils.COLOR_WHITE;
      }
      else if (id>=2000 && id<2999)
      {
         partOfStart = true;
         colorIfPartOfStart = GenericUtils.COLOR_BLACK;         
      }
      else
      {
         partOfStart = false;
         colorIfPartOfStart = GenericUtils.COLOR_NEUTRAL;             
      }      
                 
      this.color = GenericUtils.COLOR_NEUTRAL;
   }   
   
   /**
    * Initialize neighbourFromDirection 
    */
   void setNeighbourFromDirection(CloveceField neigborFromDirection)
   {
      this.neigborFromDirection = neigborFromDirection;  
      neigborFromDirection.addNeighbourToDirection(this);
   }   
   
   /**
    * add new neighbor of this field.    
    */
   private void addNeighbourToDirection(CloveceField newNeighbor)
   {
      this.neighborsToDirection.add(newNeighbor);      
   }     
   
   /** 
    * @param color
    * @return true if field is part of home of specified player (color of specified player)
    */
   public boolean isPartOfHome(int color)
   {
      return partOfHome && colorIfPartOfHome==color;
   }   
   
   /** 
    * @param color
    * @return true if field is part of start of specified player (color of specified player)
    */
   public boolean isPartOfStart(int color)
   {
      return partOfStart && colorIfPartOfStart==color;
   }       

   public int getStartFieldOnBoard()
   {
      return startFieldOnBoard;
   }      

   public CloveceField getNeigborFromDirection()
   {
      return neigborFromDirection;
   }

   public int getColor()
   {
      return color;
   }

   public void setColor(int color)
   {
      this.color = color;
   }

   public int getId()
   {
      return id;
   }

   public Collection<CloveceField> getNeighborsToDirection()
   {
      // return copy of our collection
      Collection<CloveceField> result = new HashSet<CloveceField>();
      result.addAll(neighborsToDirection);
      return result;
   } 
   
   public boolean equals(Object o)
   {
      if (!(o instanceof CloveceField))
      {
         return false;
      }
      CloveceField that  = (CloveceField)o;
      
      return getId() == that.getId(); 
   }
   
   public int hashCode()
   {
      return getId();
   }
   
   public String toString()
   {
      return new StringBuilder("CloveceField [id=").append(id).append(", color=").append(getColor()).append("]").toString(); 
   }
   
}